<?php
/*
require_once("onlineupdater.class.php");

$update = new onlineUpdater();
//add server
$update->createPassword("thepassword");
$update->addServer("http://zpilman.com/test/","sendchunk2.php");

//start update
$update->setUpdateFolder("update");
echo "Total files to upload: ".count($update->files)."<br />\n";
echo "Total folders to create: ".count($update->folders)."<br />\n";

$update->setRemainingTime(true);
foreach($update->timefile as $keyserver => $time) {
	echo "<ul><li>".$update->servers[$keyserver][0]."<ul>"."<li>Total time file 0kb upload: ".$time."</li></ul></li></ul>\n";
}
foreach($update->timefile10 as $keyserver => $time) {
	echo "<ul><li>".$update->servers[$keyserver][0]."<ul>"."<li>Total time file 10kb upload: ".$time."</li></ul></li></ul>\n";
}
foreach($update->timefolder as $keyserver => $time) {
	echo "<ul><li>".$update->servers[$keyserver][0]."<ul>"."<li>Total time folder upload: ".$time."</li></ul></li></ul>\n";
}
* */
require_once "classes/aes.class.php";
require_once "classes/aesctr.class.php";

class onlineUpdater {
	
	private $password;
	private $salt;
	
	public $files = array();
	public $folders = array();
	
	public $servers = array();
	
	public $timefile = array();
	public $timefile10 = array();
	public $timefolder = array();
	
	function onlineUpdater() {
		$fh = fopen("servers", "r");
		while(!feof($fh)) {
			$line = fgets($fh);
			if($line == null) {
				break;
			}
			$servers = explode("|", $line);
			array_push($this->servers, $servers);
		}
		fclose($fh);
	}
	
	public function addServer($server,$filename) {
		//check if exists
		$fh = fopen("servers", "r");
		while(!feof($fh)) {
			$line = fgets($fh);
			if($line == null) {
				break;
			}
			$servers = explode("|", $line);
			if($servers[0] == $server.$filename) {
				$bAllreadyExists = true;
			}
		}
		fclose($fh);
		if(!$bAllreadyExists) {
			//write upload
			$fh = fopen("upload/".$filename, "w");
			$data = '<?php
require_once "classes/aes.class.php";
require_once "classes/aesctr.class.php";

$password = "'.$this->password.'";
$salt = "'.$this->salt.'";

if(empty($_POST["cipher"])) {
	$cipher = urldecode($_GET["cipher"]);
}
else {
	$cipher = urldecode($_POST["cipher"]);
}

$decryptedstring = AesCtr::decrypt($cipher, $password, 256);

$fh = fopen("log", "a+");
fwrite($fh, "Cipher: ".date("m-d-y H:i:s")." ".$cipher."\r\n");
fwrite($fh, "Decryptedstring: ".date("m-d-y H:i:s")." ".$decryptedstring."\r\n");
fclose($fh);

if($decryptedstring == $salt) {
	function createFolder($folder) {
		if(!is_dir($folder)) {
			mkdir($folder,0755,true);
			$fh = fopen("log", "a+");
			fwrite($fh, "folder created: ".date("m-d-y H:i:s")." ".$folder."\r\n");
			fclose($fh);
		}
	}

	if(!empty($_GET["folder"])) {
		createFolder(urldecode($_GET["folder"]));
	}
	
	if(!empty($_POST)) {
		$filename = $_POST["sendtodir"].urldecode($_FILES["file"]["name"]);
		
		$fh = fopen("log", "a+");
		if(file_exists($filename)) {
			if($_POST["overwrite"]) {
				fwrite($fh, "file uploaded: ".date("m-d-y H:i:s")." ".$filename."\r\n");
				move_uploaded_file($_FILES["file"]["tmp_name"], $filename);
			}
			else {
				fwrite($fh, "file not overwritten: ".date("m-d-y H:i:s")." ".$filename."\r\n");
			}
		}
		else {
			fwrite($fh, "file uploaded: ".date("m-d-y H:i:s")." ".$filename."\r\n");
			move_uploaded_file($_FILES["file"]["tmp_name"], $filename);
		}
		fclose($fh);
	}
}
';
			fwrite($fh, $data);
			fclose($fh);
			//write servers
			$fh = fopen("servers", "a+");
			$data = $server.$filename."|".$this->password."|".$this->salt."|\n";
			fwrite($fh, $data);
			fclose($fh);
		}
	}
	
	public function createPassword($password) {
		$this->salt = substr(str_shuffle(str_repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890",24)),0,24);
		$this->password = md5(md5(md5($password)));
	}
	
	public function setPassword($password,$salt) {
		$this->password = $password;
		$this->salt = $salt;
	}
	
	public function setUpdateFolder($folder) {
		if(is_dir($folder)) {
			if($handle = opendir($folder)) {
				while(false !== ($object=readdir($handle))) {
					if($object != "." && $object != "..") {
						if(is_dir($folder."/".$object)) {
							array_push($this->folders, $folder);
							$this->setUpdateFolder($folder."/".$object);
						}
						else {
							array_push($this->files, $folder."/".$object);
						}
					}
				}
			}
		}
	}
	
	public function post($file,$sendtodir="",$url,$overwrite=true,$type="php") {
		$cipher =  AesCtr::encrypt($this->salt, $this->password, 256);
		$cipher = urlencode($cipher);
		
		if($type == "curl") {
			$file = getcwd().'/'.$file;
			$ch = curl_init($url);
			curl_setopt($ch, CURLOPT_POSTFIELDS, array("file"=>"@$file","overwrite"=>$overwrite,"sendtodir"=>$sendtodir,"cipher"=>$cipher));
			curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
			$postResult = curl_exec($ch);
			curl_close($ch);
		}
		else {
			$randomstring 		= substr(str_shuffle(str_repeat("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",8)),0,8);
			$aExtra				= array("overwrite"=>$overwrite,"sendtodir"=>$sendtodir,"cipher"=>$cipher);
			$before				= "";
			foreach($aExtra as $key => $value) {
				$before .= "--$randomstring\n";
				$before .= "Content-Disposition: form-data; name=".$key."\n\n".$value."\n";
			}
			$before .= 	"--".$randomstring."\nContent-Disposition: form-data; name=\"file\"; filename=\"$file\"\n\n".file_get_contents($file)."\n\n--$randomstring--\n";
			$params = array("http" => array(
		           "method" => "POST",
		           "header" => "Content-Type: multipart/form-data; boundary=".$randomstring,
		           "content" => $before
			));
			$ctx = stream_context_create($params);
			$fp = fopen($url, "rb", false, $ctx);
			if(!$fp) {
				throw new Exception("Problem with $url, $php_errormsg");
			}
			$response = @stream_get_contents($fp);
			if($response === false) {
				throw new Exception("Problem reading data from $url, $php_errormsg");
			}
			return $response;
		}
	}
	
	public function setRemainingTime($b) {
		foreach($this->servers as $value) {
			$this->setPassword($value[1],$value[2]);
			$time_start = $this->microtimefloat();
			$this->post("tests/testfile","",$value[0],true,"curl");
			$time_end = $this->microtimefloat();
			array_push($this->timefile,($time_end - $time_start));
				
			$time_start = $this->microtimefloat();
			$this->setPassword($value[1],$value[2]);
			$this->post("tests/testfile10","",$value[0],true,"curl");
			$time_end = $this->microtimefloat();
			array_push($this->timefile10,($time_end - $time_start));
				
			$time_start = $this->microtimefloat();
			$cipher =  AesCtr::encrypt($value[2], $value[1], 256);
			$fh = fopen($value[0]."?folder=".urlencode("testfolder")."&cipher=$cipher", "r");
			fclose($fh);
			$time_end = $this->microtimefloat();
			array_push($this->timefolder,($time_end - $time_start));
		}
		return true;
	}
	
	public function microtimefloat() {
		list($usec, $sec) = explode(" ", microtime());
		return ((float)$usec + (float)$sec);
	}
	
}